Muziek voor de moderne mens#
Introductie#
Er wordt tegenwoordig dagelijks nieuwe muziek uitgebracht door verschillende artiesten. Onze dataset bevat alleen al gegevens van meer dan 278.000 nummers op Spotify, uit de jaren 1960 tot 2022. Al deze nummers hebben attributen zoals dansbaarheid, vrolijkheid, toonsoort, populariteit, energie en nog veel meer. Deze muziek kan door mensen worden beluisterd via de streamingdienst Spotify. Wat kan er gezegd worden over de verandering van muziek in de afgelopen jaren? Is muziek net zoveel veranderd als de mens? De mens is namelijk in bepaalde opzichten veranderd in de afgelopen jaren. De moderne technologische mens, ook wel de Homo Digitalis genoemd, is een mens die omringd is door technologie, waarvan de gevolgen nog niet helemaal duidelijk zijn (Valkenburg & Peter, 2007). Uit onderzoek naar Nederlandse jongeren blijkt dat deze moderne mens een verkort concentratievermogen heeft, een verslechterde nachtrust en mindere studieresultaten door de opkomst van social media in de afgelopen decennia (Kloosterman & Van Beuningen, 2015). Bovendien zijn de huidige Nederlandse jongeren minder gelukkig dan dat jongeren 20 jaar geleden waren(CBS, 2019), ook in Amerika is er een grote stijging van angststoornissen onder mensen (Goodwin et al., 2020). Maar tegelijkertijd is diezelfde moderne mens meer verbonden dan ooit, is informatieoverdracht sneller dan ooit en vindt er een grote globalisatie plaats. In hoeverre heeft de muziek zich moeten aanpassen om bij deze mensen aan te sluiten? Houdt muziek überhaupt rekening met de veranderende mens? Zijn het juist de populaire nummers die van de norm afwijken, of juist meegaan met de veranderende mens?
Dataset en Preprocessing
#
Dataset
De Spotify 6k dataset die in het verhaal wordt gebruikt, bevat informatie over meer dan 278.000 nummers op Spotify. Deze dataset wordt regelmatig bijgewerkt met behulp van de Spotify API. Nieuwe nummers worden toegevoegd en de API verzamelt verschillende attributen van nummers. Deze attributen omvatten onder andere populariteit, dansbaarheid, energie, toonsoort, luidheid, positiviteit en nog veel meer. Ook categorische attributen zoals artiestennaam, albumnaam en genre zijn beschikbaar in de database. Dankzij de vele gekwantificeerde attributen in de dataset kunnen berekeningen en vergelijkingen worden uitgevoerd op muzieknummers, wat interessante informatie oplevert.
Preprocessing
Voor het preprocessen van de dataset is er eerst een tijdsperiode vastgesteld van 1960 t/m 2022. Er waren namelijk erg weinig nummers uit de jaren voor 1960 in de dataset en het jaar 2023 was nog niet compleet. Vervolgens zijn rijen met Nan-waardes uit de dataset gehaald. Tenslotte waren er bepaalde kolommen die een type ‘str’ hadden, maar eigenlijk het type ‘list’ moesten hebben. Deze kolommen zijn dan ook omgezet en het databestand is opgeslagen in een pickle-bestand. Dit bestandstype neemt namelijk minder ruimte in beslag dan een csv-bestand en daarnaast slaat een pickle-bestand wél de datatypes op.
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.subplots as sp
import plotly.express as px
import plotly.io as io
io.templates.default = 'plotly_dark'
main_dataset = pd.read_pickle('processed_dataset.pkl')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_19104\2288779447.py in <module>
8 io.templates.default = 'plotly_dark'
9
---> 10 main_dataset = pd.read_pickle('processed_dataset.pkl')
~\anaconda3\envs\jupyterbook\lib\site-packages\pandas\io\pickle.py in read_pickle(filepath_or_buffer, compression, storage_options)
215 # RawIOBase, BufferedIOBase, TextIOBase, TextIOWrapper, mmap]";
216 # expected "IO[bytes]"
--> 217 return pickle.load(handles.handle) # type: ignore[arg-type]
218 except excs_to_catch:
219 # e.g.
ValueError: unsupported pickle protocol: 5
#@title Processing
# Dataset groeperen, juiste datumformaat, gemiddeldewaarde en juiste jaartelling
# Zorg ervoor dat de 'release_date' kolom een datumformaat heeft
main_dataset['release_date'] = pd.to_datetime(main_dataset['release_date'])
# Groepeer de dataset per jaar en bereken de gemiddelde waarden
grouped_dataset = main_dataset.groupby(main_dataset['release_date'].dt.year).mean().reset_index()
# Hernoem de kolom 'release_date' naar 'year'
grouped_dataset = grouped_dataset.rename(columns={'release_date': 'year'})
# Selecteer de relevante kolommen uit de dataset main_dataset en hernoem indien nodig
selected_columns = main_dataset[['release_date', 'artists_names', 'name']].rename(columns={'release_date': 'year'})
selected_columns['year'] = selected_columns['year'].dt.year.astype('int64') # Converteer naar int64
# Voeg de kolommen toe aan grouped_dataset op basis van de sleutelkolommen
grouped_dataset = grouped_dataset.merge(selected_columns, on='year')
grouped_dataset['name_x'] = grouped_dataset['name']
C:\Users\david\AppData\Local\Temp\ipykernel_20204\467782972.py:8: FutureWarning: The default value of numeric_only in DataFrameGroupBy.mean is deprecated. In a future version, numeric_only will default to False. Either specify numeric_only or select only columns which should be valid for the function.
grouped_dataset = main_dataset.groupby(main_dataset['release_date'].dt.year).mean().reset_index()
#@title Processing 2
# DATASET POPULAIRSTE ARTIESTEN + NUMMER PER JAAR
# Maak een kopie van de main_dataset
popularity_set = main_dataset.copy()
# Zorg ervoor dat de 'release_date' kolom een datetimewaarde bevat
popularity_set['release_date'] = pd.to_datetime(popularity_set['release_date'], errors='coerce')
# Voeg een extra kolom toe voor het jaar van elke release
popularity_set['year'] = popularity_set['release_date'].dt.year
# Wijzig de waarden in de 'artists_names'-kolom
popularity_set['artists_names'] = popularity_set['artists_names'].apply(lambda x: x[0] if isinstance(x, list) else x)
# Groepeer de dataset per jaar en artiest en bereken het gemiddelde van de populariteit
popularity_set = popularity_set.groupby(['year', 'artists_names', 'name'])['popularity'].mean().reset_index()
# Voor elke jaar, selecteer de rij met de hoogste gemiddelde populariteit
artist_max_popularity = popularity_set.loc[popularity_set.groupby('year')['popularity'].idxmax()]
#@title Processing 3
# DATASET MET FAVO ARTIEST DAT JAAR MEERDERE NUMMERS
# Het jaar extraheren uit de 'release_date'-kolom in main_dataset
main_dataset['year'] = pd.to_datetime(main_dataset['release_date']).dt.year
# Opschonen van 'artists_names'-kolom in beide datasets
main_dataset_2 = main_dataset.copy()
main_dataset_2['artists_names'] = main_dataset_2['artists_names'].apply(lambda x: x[0] if isinstance(x, list) else x)
artist_max_popularity['artists_names'] = artist_max_popularity['artists_names'].apply(lambda x: x[0] if isinstance(x, list) else x)
# Samenvoeging uitvoeren op basis van 'artists_names' en 'year'
favo_artist_numbers = pd.merge(main_dataset_2, artist_max_popularity, on=['artists_names', 'year'], how='inner')
favo_artist_numbers = favo_artist_numbers.sort_values(by='year')
# Nieuwe dataset weergeven
#display(favo_artist_numbers)
#@title Haady geen idee
# Groepeer de gegevens op basis van het jaar en bereken het gemiddelde per jaar
favo_artist_numbers_mean = favo_artist_numbers.groupby('year').mean().reset_index()
# Optioneel: Verwijder onnodige kolommen die niet nodig zijn in de nieuwe dataset
favo_artist_numbers_mean = favo_artist_numbers_mean.drop(['popularity_y'], axis=1)
# Selecteer de relevante kolommen uit de dataset favo_artist_numbers
selected_columns = favo_artist_numbers[['year', 'name_x', 'artists_names']]
# Voeg de kolommen toe aan favo_artist_numbers_mean op basis van het jaar
favo_artist_numbers_mean = favo_artist_numbers_mean.merge(selected_columns, on='year')
C:\Users\david\AppData\Local\Temp\ipykernel_20204\458419794.py:3: FutureWarning: The default value of numeric_only in DataFrameGroupBy.mean is deprecated. In a future version, numeric_only will default to False. Either specify numeric_only or select only columns which should be valid for the function.
favo_artist_numbers_mean = favo_artist_numbers.groupby('year').mean().reset_index()
#@title Make Trace: Gemiddelde duur van nummers per jaar
# DATASET VOOR EERSTE FRAME MET TOTAAL AANTAL NUMMERS EN LENGTE MUZIEK
# Zorg ervoor dat de 'release_date' kolom een datumformaat heeft
main_dataset['release_date'] = pd.to_datetime(main_dataset['release_date'])
# Filter de dataset om alleen gegevens vanaf 1960 te bevatten
filtered_dataset = main_dataset[main_dataset['release_date'].dt.year >= 1960]
# Groepeer de dataset per jaar en tel het aantal nummers
grouped_dataset_songs = filtered_dataset.groupby(filtered_dataset['release_date'].dt.year).size().reset_index(name='num_songs')
# Maak de staafdiagram voor aantal nummers per jaar
fig_songs = go.Figure(data=go.Bar(x=grouped_dataset_songs['release_date'], y=grouped_dataset_songs['num_songs']))
fig_songs.update_layout(
title='Aantal Nummers per Jaar',
xaxis=dict(title='Jaar', tickangle=45),
yaxis=dict(title='Aantal Nummers')
)
# Een kopie maken van de dataset en deze "time_set" noemen
time_set = main_dataset.copy()
# Omzetten van de 'release_date' naar het juiste datatype (bijv. datetime)
time_set['release_date'] = pd.to_datetime(time_set['release_date'])
# Omzetten van 'release_date' naar jaarformaat
time_set['release_year'] = time_set['release_date'].dt.year
time_set = time_set[time_set['release_year'] >= 1960]
# Groeperen op 'release_year' en het gemiddelde van 'duration_ms' per tien jaar berekenen
time_set['release_decade'] = (time_set['release_year'] // 10) * 10
avg_duration_per_decade = time_set.groupby('release_decade')['duration_ms'].mean().reset_index()
#@title Plot Graph: Aantal nummers per jaar & Gemiddelde duur van nummers per jaar
# Maak de staafdiagram voor gemiddelde duur per tien jaar
fig_duration = go.Figure(data=go.Bar(x=avg_duration_per_decade['release_decade'], y=avg_duration_per_decade['duration_ms']))
fig_duration.update_layout(
title='Gemiddelde duur nummer per tien jaar',
xaxis=dict(title='Decennium'),
yaxis=dict(title='Gemiddelde duur')
)
# Combineer de twee plots in één visualisatie
fig_combined = sp.make_subplots(rows=2, cols=1, subplot_titles=['Aantal Nummers per Jaar', 'Gemiddelde duur nummer per tien jaar in milliseconden'])
fig_combined.add_trace(fig_songs.data[0], row=1, col=1)
fig_combined.add_trace(fig_duration.data[0], row=2, col=1)
# Update de legenda-tekst
fig_combined.update_traces(
name='Nummers per Jaar',
selector=dict(name='trace0')
)
fig_combined.update_traces(
name='Gemiddelde duur nummer per jaar',
selector=dict(name='trace1')
)
fig_combined.update_layout(height=800, showlegend=True)
fig_combined.show()
Verschuiving van de industrie standaarden#
In de hierboven te vinden staafdiagrammen wordt een verschuiving getoond in het muzieklandschap. Aan het begin van de eerste (blauwe) grafiek, rond 1960, was er een relatief laag aantal geproduceerde nummers. Volgens Gay & Théberge (1999) waren de mogelijkheden voor muziekproductie destijds beperkt tot een selecte groep professionele artiesten en producers, aangezien muziekinstrumenten en opnameapparatuur zowel technisch complex als duur waren.
Terwijl we ons langs de tijdlijn verplaatsen, is er een gestage groei zichtbaar in het aantal geproduceerde nummers. Deze groei begint aan snelheid te winnen rond de jaren 80 en 90. Kretschmer, Klimis, & Wallis (2001) suggereren dat de toenemende toegankelijkheid van digitale technologieën zoals MIDI en digitale opname hardware het mogelijk maakt voor meer mensen om muziek te maken.
Het bereiken van de 21e eeuw markeert een bijna exponentiële toename in de productie van nummers, zoals zichtbaar is in de scherpe opwaartse trend in de grafiek. Barker en Malony (2012) benadrukt dat de opkomst van online platforms zoals Spotify een cruciale rol speelde in deze fase, omdat ze het delen en consumeren van muziek democratiseren.
In de tweede diagram wordt duidelijk dat rond de jaren ‘80 en ‘90 er een daling is in de gemiddelde liedjes lengte, mogelijk veroorzaakt door de opkomst van de muziekvideo, die aantrekkelijker werd met kortere, visueel boeiende nummers (Vernallis, 2004).
In de 21e eeuw, met de opkomst van digitale streaming platforms zoals Spotify en Apple Music, daalde de gemiddelde lengte verder. Dit kan te maken hebben met de voorkeur van deze platforms voor nummers die vaker gestreamd worden, en kortere nummers kunnen vaker binnen een bepaalde tijd worden gestreamd (Barker & Malony, 2013).
Tegen 2022 is de gemiddelde duur van de liedjes met 40% gedaald ten opzichte van 1970, wat de verschuivingen in consumptiepatronen, technologische veranderingen en de economische druk van de muziekindustrie reflecteert.
Tegen de tijd dat we 2022 bereiken, is de groei in het aantal geproduceerde nummers zo groot dat de grafiek bijna verticaal lijkt te gaan. Dit komt overeen met de bevindingen van BOP Consulting (2015) die benadrukken hoe de groei van de wereldbevolking, gecombineerd met de economische waarde van de muziekindustrie, bijgedragen heeft aan een explosieve groei in muziekproductie
grouped_dataset.groupby('year').mean(numeric_only=True)['valence'].index
Int64Index([1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970,
1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981,
1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992,
1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014,
2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022],
dtype='int64', name='year')
#@title Plot Graph: Jaarlijkse gemiddelde waardes: Valence, Energy en Danceability
# Converteer 'valence', 'energy' en 'danceability' naar percentages
grouped_dataset['valence'] = grouped_dataset['valence']
grouped_dataset['energy'] = grouped_dataset['energy']
grouped_dataset['danceability'] = grouped_dataset['danceability']
# Variabelen om toe te voegen aan de grafiek
variables = ['valence', 'danceability', 'energy']
# Maak de grafiek met Plotly
fig = go.Figure()
for variable in variables:
fig.add_trace(go.Scatter(x=grouped_dataset.groupby('year').mean(numeric_only=True)[variable].index,
y=grouped_dataset.groupby('year').mean(numeric_only=True)[variable],
mode='lines',
name=variable))
fig.update_traces(hoverinfo=None)
fig.update_layout(
title='Jaarlijkse gemiddelde waardes: Valence, Energy en Danceability',
xaxis=dict(title='Jaar', tickangle=45),
yaxis=dict(title='Percentile'),
width=800,
height=400,
)
fig.show()
Drie variabelen, drie periodes#
In de bovenstaande grafiek worden drie variabelen uit de dataset geplot: Valence (Valentie), Danceeability (Dansbaarheid) en Energy (Energie). Er is gekozen voor deze drie variablene omdat met deze waardes er mogelijk een link gelegd kan worden met de emotionele staat van de Homo Digitales.
De grafiek kan op eerste oog verdeeld worden in drie delen: 1960 - 1980, 1980 - 2000 en 2000 - 2022. Wat opvalt aan deze drie delen is dat in het gedeelte van 1960 - 1980 de drie waardes richting elkaar groeien. Vooral Energy is hiervoor een goed voorbeeld. Een mogelijke verklaring voor deze verschijning kan zijn dat er in deze periode nieuwe muziek genres opkomend waren zoals pop en rock. Dit zijn genres met over het algemeen een hoger energie niveau.
De tweede periode, 1980 - 2000, beweegt zich zijwaarts voort met weinig significante veranderingen.
De derde periode, 2000 - 2022, brengt wel wat bijzonderheden met zich mee. Zo is het duidelijk dat vanaf 2010 de valentie significtant daalt ten opzichte van de dansbaarheid en energie. Spotify dat is opgericht in 2006, Wikipedia-bijdragers-spotify (2023), bracht in 2010 hun applicatie uit. Dit zou een mogelijke verklaring kunnen zijn voor het dalen van de valentie in de muziek ide uit werd gebracht. Muziek werd voor iedereen veel dichterbij gebracht doordat iemand niet meer nummers hoefde te downloaden en het dan te luisteren via een MP3 speler. Nieuwe generaties van artiesten hebben misschien de neiging om meer introspectieve, complexe en donkere thema’s in hun muziek te verkennen.
#@title Plot Graph: Gemiddelde huidige populariteit per jaar: 1960 - 2022
# Converteer 'valence' naar percentage
grouped_dataset['popularity'] = grouped_dataset['popularity']
# Variabelen om toe te voegen aan de grafiek
variables = ['popularity']
# Maak de grafiek met Plotly
fig = go.Figure()
for variable in variables:
fig.add_trace(go.Scatter(x=grouped_dataset['year'], y=grouped_dataset[variable], mode='lines', name=variable))
fig.update_layout(
title='Gemiddelde huidige populariteit per jaar: 1960 - 2022 ',
xaxis=dict(title='Jaar', tickangle=45),
yaxis=dict(title='Waarde (%)'), # Aangepaste y-as label
width=800,
height=400
)
fig.show()
Hoe Spotify muziek populair maakte#
In de bovenstaande grafiek, is er een significante daling in de populariteit van muziek tussen 1980 en 2010, gevolgd door een sterke toename na 2010. Dit patroon kan worden verklaard door een aantal factoren, waaronder veranderingen in technologie, muziekindustrie en maatschappelijke trends.
Verschruiving in genres#
Er zijn meerdere factoren die hebben bijgedragen aan de afname van de populariteit van bepaalde muziekgenres tussen 1980 en 2010. Ten eerste toont onderzoek aan dat er in deze periode een significante verandering in muziekstijlen heeft plaatsgevonden. Genres zoals rock en pop uit de jaren 80 hebben aan populariteit verloren, terwijl nieuwere stijlen zoals hiphop en elektronische muziek prominenter zijn geworden (North & Hargreaves, 2008).
Het internet#
Ten tweede heeft de opkomst van het internet in deze periode de manier waarop muziek wordt geconsumeerd ingrijpend veranderd. Uit onderzoek is aangetoond dat de digitalisering van muziek heeft geleid tot een toename van digitale downloads en online streaming. Dit heeft op zijn beurt bijgedragen aan een aanzienlijke daling van de traditionele albumverkoop, wat een andere mogelijke verklaring biedt voor de afname van de populariteit van sommige muziekgenres tijdens deze periode (Waldfogel, 2015).
Streamings diensten#
De plotselinge stijging van de populariteit van muziek na 2010, het jaar dat de Spotify-app werd gelanceerd, kan grotendeels worden toegeschreven aan de veranderingen in de manier waarop mensen muziek consumeren. Spotify en andere muziekstreamingdiensten hebben het gemakkelijker gemaakt voor mensen om toegang te krijgen tot een breder scala aan muziek dan ooit tevoren. Dit heeft niet alleen geleid tot een toename van de algemene consumptie van muziek, maar ook tot de mogelijkheid voor artiesten buiten de traditionele muziekindustrie om hun muziek te verspreiden en een publiek te vinden.
Bovendien hebben streamingdiensten zoals Spotify de muziekindustrie gedemocratiseerd door artiesten van alle groottes de mogelijkheid te geven om hun muziek wereldwijd te distribueren. Dit heeft de deur geopend voor een veel grotere diversiteit aan muziek en artiesten, wat heeft bijgedragen aan de toename van de populariteit van muziek na 2010.
#@title Plot graph: Most popular songs and their artists per year
# Aangepaste functie om de 'artists_names' te formatteren
def format_artists_names(artists_names):
return f"artist name: {artists_names}"
# Dataframe voor de scatterplot
scatter_data = artist_max_popularity[['year', 'popularity', 'name', 'artists_names']]
# Scatterplot met verschillende kleuren en marker grootte op basis van 'popularity' kolom
fig = px.scatter(scatter_data, title='Populairste nummer en corresponerende artiest/band per jaar', x='year', y='popularity', color='artists_names', size='popularity',
hover_data=['name', 'artists_names'])
# Weergave van het scatterplot
fig.show()
#@title Plot Graph: Average vs Most populair Artist average for Valence, Energy & Danceability
# Functie om een lijngrafiek toe te voegen
def add_line_trace(fig, x, y, name, hovertemplate, customdata = None):
fig.add_trace(go.Scatter(
x=x,
y=y,
mode='lines',
name=name,
hovertemplate=hovertemplate,
customdata=customdata
))
# Maak de drie lijngrafieken
fig_valence = go.Figure()
add_line_trace(fig_valence, grouped_dataset.groupby('year').mean(numeric_only=True)['valence'].index,
grouped_dataset.groupby('year').mean(numeric_only=True)['valence'],
'Average Valence', '<b>Year:</b> %{x}<br><b>Average Valence:</b> %{y}<br>')
add_line_trace(fig_valence, favo_artist_numbers_mean.groupby('year').mean(numeric_only=True)['valence'].index,
favo_artist_numbers_mean.groupby('year').mean(numeric_only=True)['valence'],
'Favorite Average Valence', '<b>Year:</b> %{x}<br><b>Favorite Average Valence:</b> %{y}<br>'
'<b>Artists Name:</b> %{customdata[1]}<extra></extra>',
np.column_stack((list(favo_artist_numbers_mean.drop_duplicates(subset=['year'], keep='first').sort_values('year')['name_x']),
list(favo_artist_numbers_mean.drop_duplicates(subset=['year'], keep='first').sort_values('year')['artists_names']))))
fig_valence.update_layout(title='Gemiddelde Valence per jaar vs Populairste artiest gemiddelde Valence per jaar', height=300)
#fig_valence.show()
fig_energy = go.Figure()
add_line_trace(fig_energy, grouped_dataset.groupby('year').mean(numeric_only=True)['energy'].index,
grouped_dataset.groupby('year').mean(numeric_only=True)['energy'],
'Average Energy', '<b>Year:</b> %{x}<br><b>Average Energy:</b> %{y}<br>')
add_line_trace(fig_energy, favo_artist_numbers_mean.groupby('year').mean(numeric_only=True)['energy'].index,
favo_artist_numbers_mean.groupby('year').mean(numeric_only=True)['energy'],
'Favorite Average Energy', '<b>Year:</b> %{x}<br><b>Favorite Average Energy:</b> %{y}<br>'
'<b>Artists Name:</b> %{customdata[1]}<extra></extra>',
np.column_stack((list(favo_artist_numbers_mean.drop_duplicates(subset=['year'], keep='first').sort_values('year')['name_x']),
list(favo_artist_numbers_mean.drop_duplicates(subset=['year'], keep='first').sort_values('year')['artists_names']))))
fig_energy.update_layout(title='Gemiddelde Energy per jaar vs Populairste artiest gemiddelde Energy per jaar', height=300)
#fig_energy.show()
fig_danceability = go.Figure()
add_line_trace(fig_danceability, grouped_dataset.groupby('year').mean(numeric_only=True)['danceability'].index,
grouped_dataset.groupby('year').mean(numeric_only=True)['valence'],
'Average Danceability', '<b>Year:</b> %{x}<br><b>Average Danceability:</b> %{y}<br>')
add_line_trace(fig_danceability, favo_artist_numbers_mean.groupby('year').mean(numeric_only=True)['danceability'].index,
favo_artist_numbers_mean.groupby('year').mean(numeric_only=True)['danceability'],
'Favorite Average Danceability', '<b>Year:</b> %{x}<br><b>Favorite Average Danceability:</b> %{y}<br>'
'<b>Artists Name:</b> %{customdata[1]}<extra></extra>',
np.column_stack((list(favo_artist_numbers_mean.drop_duplicates(subset=['year'], keep='first').sort_values('year')['name_x']),
list(favo_artist_numbers_mean.drop_duplicates(subset=['year'], keep='first').sort_values('year')['artists_names']))))
fig_danceability.update_layout(title='Gemiddelde Danceability per jaar vs Populairste artiest gemiddelde Danceability per jaar', height=300)
# Combineer de drie plots in één visualisatie
fig_combined = sp.make_subplots(rows=3, cols=1, subplot_titles=['Valence', 'Energy', 'Danceability'])
fig_combined.add_trace(fig_valence.data[0], row=1, col=1)
fig_combined.add_trace(fig_valence.data[1], row=1, col=1)
fig_combined.add_trace(fig_energy.data[0], row=2, col=1)
fig_combined.add_trace(fig_energy.data[1], row=2, col=1)
fig_combined.add_trace(fig_danceability.data[0], row=3, col=1)
fig_combined.add_trace(fig_danceability.data[1], row=3, col=1)
fig_combined.update_layout(height=900, showlegend=True)
fig_combined.show()
#@title Create Artist-[Genres] Series
#Create series with structure: artists - genres_from_artists, for every song
artist_name_genres = main_dataset.loc[:, ['artists_names', 'artists_genres']]
#Create dict with structure: artist - [genres_from_artist]
artist_genres = dict()
for i in artist_name_genres.index:
for name_index in range(len(artist_name_genres.loc[i, 'artists_names'])):
artist_genres[artist_name_genres.loc[i, 'artists_names'][name_index]] = artist_name_genres.loc[i, 'artists_genres'][name_index]
#Create series from artist-genres dict
artist_genres_series = pd.Series(artist_genres)
#@title Create Year-Genre-Percentile Dataframe
year_genre = pd.DataFrame(columns=['year', 'genre', 'percentile'])
for year in range(1960, 2023, 1):
#filter dataset on year
artists_year = main_dataset[main_dataset['release_date'].dt.year == year]
#create name_set based on artists in specific year
name_set_year = set()
for name_list in artists_year['artists_names']:
for name in name_list:
name_set_year = name_set_year | {name}
#Create series with structure artist-[genres] from only specific year
artist_genres_series_year = artist_genres_series.loc[list(name_set_year)]
#Create set with every genre in the specific year
genre_set_year = set()
for i in artist_genres_series_year:
for j in i:
genre_set_year = genre_set_year | {j}
#Make dict from the set with the count as values
genre_dict_year = {genre:0 for genre in genre_set_year}
#Count the amount of genres in the specific year and add them to the dict
for i in artist_genres_series_year:
for j in i:
genre_dict_year[j] += 1
amount_genres_year = sum([y[1] for y in sorted(genre_dict_year.items(), key=lambda x:x[1], reverse=True)])
#Add most popular genre to series
year_genre = pd.concat([year_genre, pd.DataFrame({'year':year,
'genre': [x[0] for x in sorted(genre_dict_year.items(), key=lambda x:x[1], reverse=True)[:5]],
'percentile': [(x[1]/amount_genres_year) for x in sorted(genre_dict_year.items(), key=lambda x:x[1], reverse=True)[:5]]})])
year_genre = year_genre.reset_index()
#@title Plot Graph: Top 5 meestgebruikte genres door artiesten, per jaar
# colors
color_sequence = px.colors.qualitative.Pastel + px.colors.qualitative.T10
colors = dict()
i = 0
for genre in [genre for genre in year_genre['genre'].unique()]:
colors[genre] = (color_sequence)[i % len(color_sequence)]
i += 1
# traces
data = []
# loop across the different years
for i in range(year_genre.shape[0]):
#add a separate trace for each year, ordered from smallest to largest
data.append(go.Bar(x=[year_genre.loc[i,'year']],
y=[year_genre.loc[i,'percentile']],
name=year_genre.loc[i,'genre'],
marker= dict(color=colors[year_genre.loc[i,'genre']]),
legendgroup=year_genre.loc[i,'genre'],
showlegend= year_genre.loc[i,'genre'] not in {data[x]['name'] for x in range(len(data))})) # show the legend only once for each trace
# layout
layout = dict(barmode='stack',
yaxis={'title': 'percentage', 'tickformat' : "0%"},
xaxis={'type': 'category', 'title': 'year'},
title='Top 5 meestgebruikte genres door artiesten, per jaar')
# figure
fig_genres = go.Figure(data=data, layout=layout)
fig_genres.show()
Muziekgenres steeds diverser#
In bovenstaande grafiek is te zien dat de hoeveelheid muziekgenres die gebruikt worden door artiesten steeds diverser is. Zo waren in 1960 de top 5 meestgebruikte muziekgenres nog goed voor meer dan 25% van alle gemaakte muziek. Tegenwoordig haalt de top 5 nog maar net de 5% van alle geproduceerde muziek.
!ls -lh
total 141M
-rw-r--r-- 1 david 197609 3.7M Jun 20 14:39 cleaning_data.ipynb
-rw-r--r-- 1 david 197609 22M Jun 22 17:55 DataVerhaal_Draft_Final.ipynb
-rw-r--r-- 1 david 197609 116M Jun 21 23:19 processed_dataset.pkl